package com.example.medispider.service;

import com.example.medispider.pojo.task.MedicalInstitution;
import com.example.medispider.pojo.task.Task;
import com.example.medispider.pojo.task.TaskConfig;
import com.example.medispider.service.detail.DetailDataExecutor;
import com.example.medispider.service.master.MasterDataExecutor;
import com.example.medispider.utils.YamlLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;

@Service
public class TaskExecutor {
    private final MasterDataExecutor masterDataExecutor;
    private final DetailDataExecutor detailDataExecutor;
    private final ResourceLoader resourceLoader;
    @Value("${spring.medi-spider.masterPageSize}")
    private int masterPageSize;
    @Value("${spring.medi-spider.detailPageSize}")
    private int detailPageSize;
    @Value("${spring.medi-spider.threadNum}")
    private int threadNum;
    @Value("${spring.medi-spider.insuAdmdvs}")
    private String insuAdmdvs;
    @Value("${spring.medi-spider.startupFilePath}")
    private String taskConfigFilePath;

    @Autowired
    public TaskExecutor(MasterDataExecutor masterDataExecutor, DetailDataExecutor detailDataExecutor, ResourceLoader resourceLoader) {
        this.masterDataExecutor = masterDataExecutor;
        this.detailDataExecutor = detailDataExecutor;
        this.resourceLoader = resourceLoader;
    }

    /**
     * 开始执行任务
     */
    public void runTask() {
        // 加载启动配置文件
        TaskConfig taskConfig = loadTaskConfig();
        // 遍历执行每份任务（每份激活的配置）
        for (Task task : taskConfig.getTasks()) {
            crawl(task);
        }
    }

    /**
     * 执行一次任务：先爬取结算主单数据，再根据主单数据爬取相应的明细数据
     *
     * @param task 一次任务配置
     */
    private void crawl(Task task) {
        String name = task.getName();
        String outputRootPath = task.getOutput_root_path();  //输出根目录
        String outputDirPath = outputRootPath + File.separator + name;
        File dir = new File(outputDirPath);
        if (!dir.exists()) {
            boolean mkdir = dir.mkdir();
            if (!mkdir) {
                throw new RuntimeException("创建文件夹失败：" + outputDirPath);
            }
        }
        String masterOutputFilePath = dir.getAbsolutePath() + File.separator + "结算主单.csv";     //主单数据文件路径
        String detailOutputFilePath = dir.getAbsolutePath() + File.separator + "结算明细.csv";     //明细数据文件路径
        String errorOutputFilePath = dir.getAbsolutePath() + File.separator + "error.csv";         //错误数据文件路径
        String qbegndate = task.getQbegndate();  //开始日期
        String qenddate = task.getQenddate();    //截至日期
        ArrayList<String> fixmedinsCodeList = new ArrayList<>();  //机构编码集合
        for (MedicalInstitution medicalInstitution : task.getMedical_institutions()) {
            String fixmedinsCode = medicalInstitution.getFIXMEDINS_CODE();
            fixmedinsCodeList.add(fixmedinsCode);
        }
        if (task.isActive_master()) {
            // 爬取结算数据
            masterDataExecutor.setQbegndate(qbegndate).setQenddate(qenddate).setFixmedinsCode(fixmedinsCodeList)
                    .setInsuAdmdvs(insuAdmdvs).setPageSize(masterPageSize).setThreadNum(threadNum)
                    .setOutputFilePath(masterOutputFilePath).run();
        }
        if (task.isActive_detail()) {
            // 爬取明细数据
            detailDataExecutor.setOutputFilePath(detailOutputFilePath).setMasterFilePath(masterOutputFilePath)
                    .setErrorFilePath(errorOutputFilePath).setPageSize(detailPageSize).setThreadNum(threadNum).run();
        }
    }

    /**
     * 加载启动配置文件
     *
     * @return TaskConfig
     */
    private TaskConfig loadTaskConfig() {
        try {
            Resource resource = resourceLoader.getResource(taskConfigFilePath);
            String filePath = resource.getFile().getAbsolutePath();
            // 加载启动配置文件，过滤掉未激活的配置
            return YamlLoader.loadTaskConfig(filePath);
        } catch (Exception e) {
            throw new RuntimeException("加载配置文件失败: " + taskConfigFilePath, e);
        }
    }


    public TaskExecutor setTaskConfigFilePath(String taskConfigFilePath) {
        this.taskConfigFilePath = taskConfigFilePath;
        return this;
    }


    public TaskExecutor setMasterPageSize(int masterPageSize) {
        this.masterPageSize = masterPageSize;
        return this;
    }

    public TaskExecutor setDetailPageSize(int detailPageSize) {
        this.detailPageSize = detailPageSize;
        return this;
    }

    public TaskExecutor setThreadNum(int threadNum) {
        this.threadNum = threadNum;
        return this;
    }

    public TaskExecutor setInsuAdmdvs(String insuAdmdvs) {
        this.insuAdmdvs = insuAdmdvs;
        return this;
    }


}
